/* --------------------------------------------------------------- */
/* class GUI_Scene, Scene representation in a GTK user interface.  */
/* Authors:                                                        */
/* Emilio Blazquez Sierra                                          */
/* Francisco Fernandez Castaño                                     */
/* Maria Jesus Ciudad Trujillo                                     */
/* --------------------------------------------------------------- */


#ifndef GUI_SCENE_H
#define GUI_SCENE_H

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cmath>

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <libglademm/xml.h>
#include <gtkmm.h>
#include <gtkglmm.h>

#include "Scene.h"

#define CUBE 0
#define SPHERE 1
#define CONE 2
#define CYLINDER 3
#define TOROID 4
#define MONKEY 5

#define SCALE_MAX 2
#define SCALE_MIN 0.2
#define INFINITE 9999999999


class GUIScene : public Gtk::GL::DrawingArea {

 private:
  
  /** \brief OpenGL scene, from core part. */
  Scene *scene;
  /** \brief Vector of basic models (cube, sphere, cone, cylinder, toroid and monkey) to be included directly. */
  vector<Object3D*> basic_models;

  /** \brief Begin x coordinate of mouse in order to be used for mouse motion. */
  float m_BeginX;
  /** \brief Begin y coordinate of mouse in order to be used for mouse motion. */
  float m_BeginY;

  /** \brief Scale level of the scene. */
  float m_Scale;
  
  /** \brief Angle of rotation of the scene in x axis. */
  float alpha_x;
  /** \brief Angle of rotation of the scene in y axis. */
  float alpha_y;

  /** \brief In edit mode, number of the selected triangle. Only one triangle can be selected because of the extrude operation only works with one. */
  int triangleselected;
  /** \brief In edit mode, Triangle selected. */
  Triangle *t;

  sigc::connection m_ConnectionIdle;

  static const float CLEAR_COLOR[4];
  static const float CLEAR_DEPTH;

  static const float LIGHT0_POSITION[4];
  static const float LIGHT0_AMBIENT[4];
  static const float LIGHT0_DIFFUSE[4];

  static const float LIGHT_MODEL_AMBIENT[4];
  static const float LIGHT_MODEL_LOCAL_VIEWER[1];

 public:

  GUIScene();

  /** \brief Redraw the scene. */
  void invalidate();
  /** \brief Update window synchronously. */
  void update();
  /** \brief Set view perspective. */
  bool frustum(int w, int h);
    
  /* Event handlers */

  /** \brief Button press event handler.
   * \param event : GdkEventButton */
  bool on_button_press_event(GdkEventButton* event);
  /** \brief Motion event handler.
   * \param event : GdkEventMotion */
  bool on_motion_notify_event(GdkEventMotion* event);
  void on_realize();
  /** \brief Configure event handler.
   * \param event : GdkEventConfigure */
  bool on_configure_event(GdkEventConfigure* event);
  /** \brief Expose event handler.
   * \param event : GdkEventExpose */
  bool on_expose_event(GdkEventExpose* event);
  /** \brief Unmap event handler.
   * \param event : GdkEventAny */
  bool on_unmap_event(GdkEventAny* event);
  /** \brief Idle function. */
  bool on_idle();
  /** \brief Connect idle function. */
  void idle_add();
  /** \brief Disconnect idle function. */
  void idle_remove();



 
  /** \brief Create Add menu in the up bar. */
  Gtk::Menu* create_add_menu();
  /** \brief Add a new basic object in the scene. */
  void add(int shape);
  /** \brief Select objects or triangles in the scene, depending on the mode.
      \param x : mouse x coordinate
      \param y : mouse y coordinate */
  bool select(int x, int y);
  /** \brief Process and display on the terminal the hits of the select function. Keeps the closer hit.
      \param hits : Number of hits
      \param names : Buffer where are stored the values for the selection data */
  void list_hits(GLint hits, GLuint *names);
  /** \brief Draw the scene. */
  bool draw();
  /** \brief Change between Edit and Object mode. */
  void edit_button();
  /** \brief Delete all the objects in the scene. Called when File->New is clicked. */
  void DeleteAll();
  


  /* Linked core functions. */

  /** \brief Select all the objects in the scene. Only in object mode. */
  void selectall();
  /** \brief Select the objects in the scene which are not selected currently. Only in object mode. */
  void selectinverse();
  /** \brief Unselect all the objects in the scene. Only in object mode. */
  void deselectall();
  /** \brief Rotate selected objects. Only in object mode. */
  void rotate (GLdouble degree, TAxis axis);
  /** \brief Scale selected objects. Only in object mode. */
  void scale  (GLdouble factor, TAxis axis);
  /** \brief Move selected objects. Only in object mode. */
  void move (Vertex3D pos);
  /** \brief Extrude selected triangle. Only in edit mode. */
  void extrude(int dist);
  /** \brief Delete selected objects. Only in object mode. */
  void delete_objects();
  /** \brief Get scene mode (Edit mode or Object mode).
      \return NORMAL, SELECTED or EDITED. */
  TState get_state();
  /** \brief Get the number of selected objects in the scene.
      \return number of selected objects.*/
  int get_n_selected_objects();
    

};

#endif
